﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Net;
using System.Windows.Forms;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Security.Policy;
using System.Drawing;
using System.Windows.Forms.VisualStyles;
using System.Drawing.Printing;
using System.Data;
using static 用户管理系统.MyPrint;
using 用户管理系统.Properties;
using System.Runtime.Remoting.Messaging;
using System.Data.SqlTypes;
using static 用户管理系统.MyWeb;

namespace 用户管理系统
{
    internal class MyClass
    {
        public static int GetHeight(int height, double scale = 1.3)
        {
            return Convert.ToInt32(height * scale);
        }

    }

    /// <summary>
    /// 全局配置
    /// </summary>
    public class ConfigInfo
    {
        public MyServer MyServer { get; set; }
        public MyDgv MyDgv { get; set; }
        public MyColors MyColors { get; set; }

        public MyPrintInfo MyPrintInfo { get; set; }
        //private readonly string[] msg =
        //{
        //    "行情涨跌不定，价格以当日为准",
        //    "整机不包邮默认顺丰到付  可全部发散件或部分发散件",
        //    "云南玉溪24年老店 诚信经营  以上价格仅供参考，具体联系小黄车客服",
        //};

        /// <summary>
        /// 初始化全局配置类
        /// </summary>
        public ConfigInfo()
        {
            this.MyServer = new MyServer();
            this.MyPrintInfo = new MyPrintInfo();
            this.MyColors = new MyColors();
            this.MyDgv = new MyDgv();
        }

    }

    /// <summary>
    /// 服务端配置信息类
    /// </summary>
    public class MyServer
    {
        public string HostAddress { get; set; }
        public int WebPort { get; set; }
        public int ConnTimeOut { get; set; }

        /// <summary>
        /// 初始化服务端配置信息
        /// </summary>
        public MyServer()
        {
            this.HostAddress = "xtf.tf-pc.com";
            this.WebPort = 81;
            this.ConnTimeOut = 15;
        }

    }

    /// <summary>
    /// 全局颜色列表
    /// </summary>
    public class MyColors
    {
        public Dictionary<string, Color> Colors { get; set; }
        public MyColors()
        {
            Colors = new Dictionary<string, Color>
                {
                    { "dgv表-隔行背景",(Color) new ColorConverter().ConvertFrom("#F2F2F2") },
                    { "深青蓝",(Color) new ColorConverter().ConvertFrom("#34959D") },
                    { "浅蓝",(Color)new ColorConverter().ConvertFrom("#BFE5EA") },
                };
        }
    }

    /// <summary>
    /// 外观属性类
    /// </summary>
    public class Attribute
    {
        public string Text { get; set; }
        public Font Font { get; set; }
        public Color ForeColor { get; set; }
        public Color BackColor { get; set; }
        public Attribute(string text, Font font, Color foreColor = default, Color backColor = default)
        {
            this.Text = text;
            this.Font = font;
            this.ForeColor = foreColor == default ? Color.FromKnownColor(KnownColor.WindowText) : foreColor;
            this.BackColor = backColor == default ? Color.FromKnownColor(KnownColor.Window) : backColor;
        }
    }

    /// <summary>
    /// DGV属性类
    /// </summary>
    public class MyDgv
    {
        public Attribute MainTableHeader { get; set; }
        public Attribute MainTableText { get; set; }
        public Attribute SeconTableHeader { get; set; }
        public Attribute SeconTableText { get; set; }
        public Attribute SelectText { get; set; }
        public Attribute UserInfoShow { get; set; }
        public Attribute UserCfgShow { get; set; }
        public Attribute UserMoney { get; set; }

        public MyDgv()
        {
            MyColors myColors = new MyColors();
            this.MainTableHeader = new Attribute("", new Font("微软雅黑", 11f, FontStyle.Bold), Color.White, myColors.Colors["深青蓝"]);
            this.MainTableText = new Attribute("", new Font("微软雅黑", 11f), Color.Black, Color.White);
            this.SeconTableHeader = new Attribute("", new Font("微软雅黑", 10f, FontStyle.Bold), Color.White, myColors.Colors["深青蓝"]);
            this.SeconTableText = new Attribute("", new Font("微软雅黑", 10f), Color.Black, Color.White);
            this.SelectText = new Attribute("", new Font("微软雅黑", 11f), Color.Black, myColors.Colors["浅蓝"]);
            this.UserInfoShow = new Attribute("", new Font("宋体", 12f, FontStyle.Bold), Color.Blue);
            this.UserCfgShow = new Attribute("", new Font("宋体", 12f, FontStyle.Bold), Color.Blue);
            this.UserMoney = new Attribute("", new Font("微软雅黑", 12f, FontStyle.Bold), Color.Red);
        }
    }


    /// <summary>
    /// 网络相关类，检查网络连接是否正常
    /// </summary>
    public class MyNetwork
    {
        private readonly MyLog myLog = new MyLog();
        public bool PortCheck(string hostAddress, int port, int timeOut = 500, string mode = "tcp")
        {
            Socket sock = null;
            TcpClient tcp = null;
            bool status = false;
            try
            {
                //CancellationTokenSource c = new CancellationTokenSource();
                //CancellationToken token = c.Token;
                //Debug.Print(tcp?"1");
                Thread t = new Thread(new ThreadStart(() =>
                {
                    IPAddress ipa = Dns.GetHostEntry(hostAddress).AddressList[0];
                    //IPAddress ipa = IPAddress.Parse(ip);
                    IPEndPoint point = new IPEndPoint(ipa, port);
                    switch (mode)
                    {
                        case "tcp":
                            tcp = new TcpClient();
                            tcp.Connect(point);
                            //tcp =new TcpClient(ip,port);
                            break;
                        case "sock":
                            sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                            sock.Connect(point);
                            break;
                    }
                    status = true;
                }));
                t.Start();
                Thread.Sleep(timeOut);
                if (!status)
                {
                    t.Abort();
                    Debug.Print($"1.端口{port}连接失败");
                    return status;
                }
            }
            catch (SocketException ex)
            {
                myLog.FileWriteLine(myLog.ERROR_DATE, ex.ToString());
                return status;
            }
            finally
            {
                switch (mode)
                {
                    case "tcp":
                        sock?.Close();
                        sock?.Dispose();
                        break;
                    case "sock":
                        tcp?.Close();
                        break;
                }
            }
            //Debug.Print($"端口{port}连接成功");
            return status;
        }
    }

    /// <summary>
    /// 数据匹配类
    /// 正则匹配
    /// </summary>
    public class DataMatch
    {
        //正则确实数据是否匹配，返回bool
        public bool IsMatch(string input, string pattern)
        {
            pattern = pattern.Replace("+", "\\+");
            pattern = pattern.Replace(".", "\\.");
            Regex r = new Regex(pattern, RegexOptions.IgnoreCase);
            Match match = r.Match(input);
            if (match.Success)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        //正则匹配数据，返回List<string>
        public List<string> MatchData(string input, string pattern)
        {
            Regex r = new Regex(pattern, RegexOptions.IgnoreCase);
            List<string> rList = new List<string>();
            MatchCollection matchs = r.Matches(input);
            foreach (Match item in matchs)
            {
                if (!string.IsNullOrEmpty(item.Value))
                {
                    rList.Add(item.Value);
                }
            }
            return rList;
        }
    }


    /// <summary>
    /// 日志类
    /// </summary>
    public class MyLog
    {
        public readonly int INFO_DATE = 0x01;
        public readonly int WARN_DATE = 0x02;
        public readonly int ERROR_DATE = 0x03;
        public readonly int INFO = 0x04;
        public readonly int WARN = 0x05;
        public readonly int ERROR = 0x06;
        private readonly string ProcessName = Process.GetCurrentProcess().ProcessName;
        private readonly string ProcessStartPath = Environment.CurrentDirectory;
        //private readonly string assemblyName = Assembly.GetExecutingAssembly().GetName().Name;
        public string WorkPath { get; set; }
        public System.IO.FileInfo LogFile { get; set; }
        //private ResFileInfo fiLogFile = new ResFileInfo(Environment.GetEnvironmentVariable("Temp") + "\\" + assemblyName + ".log");

        public MyLog(string logFile = null, string workPath = null)
        {
            this.LogFile = logFile == null ? new System.IO.FileInfo($"{ProcessStartPath}\\{ProcessName}.log") : new System.IO.FileInfo(logFile);
            this.WorkPath = workPath ?? Environment.CurrentDirectory;
        }

        //格式化日志输出时日期和日志class
        public string Format(int classValue, string logText)
        {
            string res;
            string logDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");

            // value 大于3则减3，保持值为1-3
            int value = classValue > 3 ? classValue - 3 : classValue;
            switch (value)
            {
                case 0x01:
                    res = "INFO";
                    break;
                case 0x02:
                    res = "WARN";
                    break;
                case 0x03:
                    res = "ERROR";
                    break;
                default:
                    res = "INFO";
                    break;
            }
            // value 大于3返回无日期的log标志
            string flag = classValue > 3 ? $"[{res}]" : $"{logDate} [{res}]";

            //包含日期、日志class，日志内容
            return string.Format("{0} {1}", flag, logText);
        }


        //控制台输出日志函数，行输出，重载
        public void ConWriteLine(string text = null, int left = 0, int top = 0)
        {
            if (left > 0 || top > 0)
            {
                //调整输出位置
                Console.SetCursorPosition(left, top);
            }
            Console.WriteLine(text);
        }

        //控制台输出日志函数，行输出，重载
        public void ConWriteLine(int classValue, string text = null, int left = 0, int top = 0)
        {
            if (left > 0 || top > 0)
            {
                //调整输出位置
                Console.SetCursorPosition(left, top);
            }
            Console.WriteLine(Format(classValue, text));
        }

        //控制台输出日志函数，重载
        public void ConWrite(string text, int left = 0, int top = 0)
        {
            if (left > 0 || top > 0)
            {
                //调整输出位置
                Console.SetCursorPosition(left, top);
            }
            Console.Write(text);
        }

        //控制台输出日志函数，重载
        public void FileWrite(int classValue, string text)
        {
            try
            {
                ConWriteLine(classValue, text);
                using (StreamWriter sw = LogFile.AppendText())
                {
                    sw.Write(Format(classValue, text));
                }
            }
            catch (Exception e)
            {
                Debug.Print(Format(ERROR_DATE, e.ToString()));
            }
        }


        //日志文件输出日志函数
        public void FileWrite(System.IO.FileInfo fi, int classValue, string text)
        {
            try
            {
                ConWriteLine(classValue, text);
                using (StreamWriter sw = fi.AppendText())
                {
                    sw.Write(Format(classValue, text));
                }
            }
            catch (Exception e)
            {
                Debug.Print(Format(ERROR_DATE, e.ToString()));
            }
        }

        //日志文件输出日志函数，行输出，重载
        public void FileWriteLine(int classValue, string text)
        {
            try
            {
                ConWriteLine(classValue, text);
                using (StreamWriter sw = LogFile.AppendText())
                {
                    sw.WriteLine(Format(classValue, text));
                }
            }
            catch (Exception e)
            {
                Debug.Print(Format(ERROR_DATE, e.ToString()));
            }
        }

        //日志文件输出日志函数，行输出，重载
        public void FileWriteLine(System.IO.FileInfo fi, int classValue, string text)
        {
            try
            {
                ConWriteLine(classValue, text);
                using (StreamWriter sw = fi.AppendText())
                {
                    sw.WriteLine(Format(classValue, text));
                }
            }
            catch (Exception e)
            {
                Debug.Print(Format(ERROR_DATE, e.ToString()));
            }
        }
    }


    public class Base64
    {
        private readonly MyLog myLog = new MyLog();
        /// <summary>
        /// 字符串编码
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public string Encode(string text)
        {
            string resBase64 = null;
            text = text.Trim();
            if (!string.IsNullOrEmpty(text))
            {
                try
                {
                    Encoding encoding = Encoding.GetEncoding("UTF-8");
                    byte[] buffer = encoding.GetBytes(text);
                    resBase64 = Convert.ToBase64String(buffer, Base64FormattingOptions.None);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"{ex.Message}\n" + ex.ToString(), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    myLog.FileWriteLine(myLog.ERROR_DATE, ex.ToString());
                }
            }
            return resBase64;
        }



        /// <summary>
        /// 字符串解码
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public string Decode(string text)
        {
            string resString = null;
            text = text.Trim();
            if (!string.IsNullOrEmpty(text))
            {
                try
                {
                    Encoding encoding = Encoding.GetEncoding("UTF-8");
                    byte[] buffer = Convert.FromBase64String(text);
                    resString = encoding.GetString(buffer);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"{ex.Message}\n" + ex.ToString(), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    myLog.FileWriteLine(myLog.ERROR_DATE, ex.ToString());
                }
            }
            return resString;
        }

        /// <summary>
        /// 字符串编码简单加密
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public string EncodeA(string text)
        {
            string resBase64 = null;
            text = text.Trim();
            if (!string.IsNullOrEmpty(text))
            {
                try
                {
                    text = Encode(text);
                    resBase64 = "L" + text.Substring(0, 10) + "M" + text.Substring(10);
                }
                catch (Exception)
                {

                }
            }
            return resBase64;
        }

        /// <summary>
        /// 字符解码并对应解密
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public string DecodeA(string text)
        {
            string resBase64 = null;
            text = text.Trim();
            if (!string.IsNullOrEmpty(text))
            {
                try
                {
                    text = text.Substring(1, 10) + text.Substring(12);
                    int num = 4 - text.Length % 4;
                    if (num < 0)
                        text = text.PadRight(text.Length + num, '=');
                    resBase64 = Decode(text);
                }
                catch (Exception)
                {

                }
            }
            return resBase64;
        }
    }

    /// <summary>
    /// Web请求类Post和Get
    /// </summary>
    public class MyWeb
    {
        //private readonly string userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36Edge/13.10586";
        private readonly MyLog myLog = new MyLog();

        public MyWeb()
        {

        }

        public MyResponse Post(string url, string jsonParams)
        {
            MyResponse myResponse = new MyResponse();
            try
            {
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);

                req.Method = "POST";

                // req.TimeOut = "800";//设置请求超时时间，单位为毫秒

                req.ContentType = "application/json";

                Debug.Print($"post => {jsonParams}");
                byte[] data = Encoding.UTF8.GetBytes(jsonParams);

                req.ContentLength = data.Length;

                using (Stream reqStream = req.GetRequestStream())
                {
                    reqStream.Write(data, 0, data.Length);

                    reqStream.Close();
                }

                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

                Stream stream = resp.GetResponseStream();

                //获取响应内容
                using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                {
                    myResponse.Datas = reader.ReadToEnd();
                }
                myResponse.Code = 0;
                myResponse.Message = "";
            }
            catch (Exception ex)
            {
                myLog.FileWriteLine(myLog.ERROR_DATE, ex.ToString());
                myResponse.Code = 999;
                myResponse.Message = ex.Message;
            }
            return myResponse;
        }

        public MyResponse Post(string url, Dictionary<string, string> dicParams, string fileName)
        {
            MyResponse myResponse = new MyResponse();
            try
            {
                #region post请求参数
                string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
                byte[] boundarybytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
                byte[] endbytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");

                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
                request.ContentType = "multipart/form-data; boundary=" + boundary;
                request.Method = WebRequestMethods.Http.Post;
                request.KeepAlive = true;
                request.Timeout = -1;

                CredentialCache credentialCache = new CredentialCache
                {
                    { new Uri(url), "Basic", new NetworkCredential("member", "secret") }
                };
                request.Credentials = credentialCache;
                request.ServicePoint.Expect100Continue = false;
                #endregion

                //发送请求数据
                requestData();

                #region 获取请求放回数据
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                using (Stream responsestream = response.GetResponseStream())
                {
                    using (StreamReader sr = new StreamReader(responsestream))
                    {
                        myResponse.Datas = sr.ReadToEnd();
                    }
                }
                #endregion

                //请求函数
                void requestData()
                {
                    using (Stream stream = request.GetRequestStream())
                    {
                        List<byte[]> lisByteArray = new List<byte[]>();
                        #region 定义参数请求key/value
                        if (dicParams != null)
                        {
                            foreach (string key in dicParams.Keys)
                            {
                                lisByteArray.Add(boundarybytes);
                                lisByteArray.Add(Encoding.UTF8.GetBytes($"Content-Disposition: form-data; " +
                                                           $"name=\"{key}\"\r\n\r\n{dicParams[key]}"));
                            }
                        }
                        #endregion

                        #region 定义文件请求
                        if (!string.IsNullOrEmpty(fileName) && File.Exists(fileName))
                        {
                            lisByteArray.Add(boundarybytes);
                            lisByteArray.Add(Encoding.GetEncoding("UTF-8").GetBytes($"Content-Disposition:form-data;" +
                                $"name=\"file\";filename=\"{Path.GetFileName(fileName)}\"\r\n"));
                            lisByteArray.Add(Encoding.GetEncoding("UTF-8").GetBytes($"Content-Type:image/jepg\r\n\r\n"));
                            lisByteArray.Add(File.ReadAllBytes(fileName));
                        }
                        #endregion

                        #region 将请求写入数据流
                        lisByteArray.Add(endbytes);             //添加结束标记
                        lisByteArray.ForEach(item =>            //遍历item写入数据流
                        {
                            stream.Write(item, 0, item.Length);
                        });
                        #endregion
                    }
                }
                myResponse.Code = 0;
                myResponse.Message = "";
            }
            catch (Exception ex)
            {
                MyLog myLog = new MyLog();
                myLog.FileWriteLine(myLog.ERROR, ex.ToString());
                myResponse.Message = ex.Message;
                myResponse.Code = 999;
            }
            return myResponse;
        }


        public void Get()
        {

        }

        public class MyResponse
        {
            public int Code { get; set; }
            public string Message { get; set; }
            public string Datas { get; set; }
        }
    }

    /// <summary>
    /// JSON处理类
    /// </summary>
    public class MyJson
    {
        #region 使用方法
        /// <summary>
        /// 方法一: JavaScriptSerializer
        /// 1.添加引用：System.Web.Extensions
        /// 2.导入命名空间：using System.Web.Script.Serialization
        /// 3.声明新对象 JavaScriptSerializer jss = new JavaScriptSerializer();
        /// 4.使用新对象jss的Serialize和Deserialize方法
        /// 方法二: JSON.NET
        /// 1.NuGet安装Newtonsoft.Json
        /// 2.添加引用：Newtonsoft.Json，默认会自动添加
        /// 3.导入命名空间：using Newtonsoft.Json; using Newtonsoft.Json.Linq;
        /// 4.直接使用JsonConvert的SerializeObject和DeserializeObject方法
        /// </summary>
        #endregion

        private readonly MyLog myLog = new MyLog();
        public MyJson() { }

        /// <summary>
        /// json序列化为string
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public string SerializeObject(object value)
        {
            try
            {
                return JsonConvert.SerializeObject(value);
            }
            catch (Exception ex)
            {
                myLog.FileWriteLine(myLog.ERROR_DATE, ex.ToString());
                return null;
            }
        }

        /// <summary>
        /// 字符串反序列化为json
        /// </summary>
        /// <typeparam name="Type"></typeparam>
        /// <param name="json"></param>
        /// <returns></returns>
        public Type DeserializeObject<Type>(string json)
        {
            Type T = default;
            try
            {
                T = JsonConvert.DeserializeObject<Type>(json);
            }
            catch (Exception ex)
            {
                myLog.FileWriteLine(myLog.ERROR_DATE, ex.ToString());
            }
            return T;
        }
    }


    /// <summary>
    /// 远程数据类
    /// </summary>
    public class WebData
    {
        public string id { get; set; }
        public string 品牌 { get; set; }
        public string 型号 { get; set; }
        public string 成本 { get; set; }
        public string 利润 { get; set; }
        public string 库存 { get; set; }
        public string 备注 { get; set; }
        public string 图片 { get; set; }
    }

    /// <summary>
    /// Query返回值
    /// </summary>
    public class UserData
    {
        public int ID { get; set; }
        public string 编号 { get; set; }
        public string 用户名称 { get; set; }
        public DateTime 购买日期 { get; set; }
        public string 联系电话 { get; set; }
        public string 销售人员 { get; set; }
        public string 装机人员 { get; set; }
        public string 详细地址 { get; set; }
        public float? 金额 { get; set; }
        public List<UserConfig> 配置 { get; set; }
        public UserData()
        {
            配置 = new List<UserConfig>();
        }
    }

    /// <summary>
    /// 用户配置类
    /// </summary>
    public class UserConfig
    {
        public int ID { get; set; }
        public string ClassID { get; set; }
        public string 类型 { get; set; }
        public string 名称 { get; set; }
        public int? 数量 { get; set; }
        public string 保修 { get; set; }
        public string 备注 { get; set; }
    }

    /// <summary>
    /// 通用信息类（公司员工、商品信息、类型）
    /// </summary>
    public class CurrencyInfo
    {
        public int ID { get; set; }
        public string 名称 { get; set; }
        public string ClassID { get; set; }
    }

    /// <summary>
    /// QueryUser请求返回用户数据
    /// 状态和返回值
    /// </summary>
    public class ResUser
    {
        public string type { get; set; }
        public int code { get; set; }
        public string message { get; set; }
        public int count { get; set; }
        public List<UserData> datas { get; set; }
        public ResUser()
        {
            this.code = -1;
            datas = new List<UserData>();
        }
    }

    /// <summary>
    /// QueryCurrency请求返回通用数据
    /// 状态和返回值
    /// </summary>
    public class ResCurrency
    {
        public string type { get; set; }
        public int code { get; set; }
        public string message { get; set; }
        public int count { get; set; }
        public List<CurrencyInfo> datas { get; set; }
        public ResCurrency()
        {
            this.code = -1;
            datas = new List<CurrencyInfo>();
        }
    }

    /// <summary>
    /// 通用请求返回数据
    /// 状态和返回值
    /// </summary>
    public class ResData
    {
        public int code { get; set; }
        public string message { get; set; }
        public int count { get; set; }
        public List<string> datas { get; set; }
        public ResData()
        {
            this.code = -1;
            datas = new List<string>();
        }
    }

    /// <summary>
    /// 该类变量名称必须全为小写
    /// 对应服务器接受的post
    /// </summary>
    public class PostData
    {
        public string action { get; set; }
        public string type { get; set; }
        public int id { get; set; }
        public string number { get; set; }
        public string name { get; set; }
        public string date { get; set; }
        public string tel { get; set; }
        public string classID { get; set; }
        public string match { get; set; }
        public int limit { get; set; }
        public Dictionary<string, string> datas { get; set; }
        public PostData()
        {
        }
    }

    /// <summary>
    /// 用户配置管理
    /// 数据查询-Query
    /// 数据提交(新增、修改、删除）-Submit
    /// </summary>
    public class MyData
    {
        private readonly MyLog myLog = new MyLog();
        private readonly MyWeb myWeb = new MyWeb();
        private readonly MyJson myJson = new MyJson();
        private readonly Dictionary<string, string> api_urls = new Dictionary<string, string>();
        //private ResFileInfo resInfo = new ResFileInfo();


        /// <summary>
        /// new 函数
        /// </summary>
        /// <param name="serverInfo"></param>
        public MyData(MyServer serverInfo)
        {
            api_urls["user_manage"] = $"http://{serverInfo.HostAddress}:{serverInfo.WebPort}/user/api/user_manage.php";
            api_urls["config_manage"] = $"http://{serverInfo.HostAddress}:{serverInfo.WebPort}/user/api/user_manage.php";
            api_urls["currency_manage"] = $"http://{serverInfo.HostAddress}:{serverInfo.WebPort}/user/api/currency_manage.php";
            api_urls["get_user"] = $"http://{serverInfo.HostAddress}:{serverInfo.WebPort}/user/api/user_get.php";       // 临时使用
            api_urls["data_sync"] = $"http://{serverInfo.HostAddress}:{serverInfo.WebPort}/user/api/data_sync.php";       // 临时使用
            api_urls["count"] = $"http://{serverInfo.HostAddress}:{serverInfo.WebPort}/user/api/count.php";       // 临时使用

        }

        /// <summary>
        /// 查询用户数据方法
        /// </summary>
        /// <param name="type"></param>
        /// <param name="id"></param>
        /// string url, string type, string number = "*", string name = "*",DateTime date = default, string tel = "*",
        /// string saleser = "*", string installer = "*"
        /// <returns></returns>
        public ResUser QueryUser(string url, PostData postData)
        {
            // 声明数据类型
            ResUser res = null;
            try
            {
                MyResponse myResponse = Operation(api_urls[url], postData);
                res = myJson.DeserializeObject<ResUser>(myResponse.Datas);
                if (res == null)
                {
                    res.code = 999;
                    res.message = "远程数据解析失败！";
                }
            }
            catch (Exception ex)
            {
                myLog.FileWriteLine(myLog.ERROR, $"Current table name: {postData.type}");
                myLog.FileWriteLine(myLog.ERROR, ex.ToString());
                res.message = ex.Message;
            }
            return res;
        }

        /// <summary>
        /// 查询通用数据方法
        /// </summary>
        /// <param name="type"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public ResCurrency QueryCurrency(string url, PostData postData)
        {
            // 声明数据类型
            ResCurrency res = null;
            try
            {
                MyResponse myResponse = Operation(api_urls[url], postData);
                res = myJson.DeserializeObject<ResCurrency>(myResponse.Datas);
                if (res == null)
                {
                    res.code = 999;
                    res.message = "远程数据解析失败！";
                }
            }
            catch (Exception ex)
            {
                myLog.FileWriteLine(myLog.ERROR, $"Current table name: {postData.type}");
                myLog.FileWriteLine(myLog.ERROR, ex.ToString());
                res.message = ex.Message;
            }
            return res;
        }


        /// <summary>
        /// 数据同步方法
        /// </summary>
        /// <param name="type"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public ResData DataSync(string url, PostData postData)
        {
            // 声明数据类型
            ResData res = null;
            try
            {
                MyResponse myResponse = Operation(api_urls[url], postData);
                res = myJson.DeserializeObject<ResData>(myResponse.Datas);
                if (res == null)
                {
                    res.code = 999;
                    res.message = "远程数据解析失败！";
                }
            }
            catch (Exception ex)
            {
                myLog.FileWriteLine(myLog.ERROR, $"Current table name: {postData.type}");
                myLog.FileWriteLine(myLog.ERROR, ex.ToString());
                res.message = ex.Message;
            }
            return res;
        }

        /// <summary>
        /// 提交数据通用方法
        /// </summary>
        /// <param name="action"></param>
        /// <param name="type"></param>
        /// <param name="id"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public ResData Submit(string url, PostData postData)
        {
            // 声明数据类型
            ResData res = null;

            try
            {
                MyResponse myResponse = Operation(api_urls[url], postData);
                res = myJson.DeserializeObject<ResData>(myResponse.Datas);
                if (res == null)
                {
                    res.code = 999;
                    res.message = "远程数据解析失败！";
                }
            }
            catch (Exception ex)
            {
                myLog.FileWriteLine(myLog.ERROR, $"Current table name: {postData.type}");
                myLog.FileWriteLine(myLog.ERROR, ex.ToString());
                res.message = ex.Message;
            }
            return res;
        }

        /// <summary>
        /// 操作数据方法，查询和提交均调用此方法
        /// </summary>
        /// <param name="postData"></param>
        /// <returns></returns>
        private MyResponse Operation(string apiUrl, PostData postData)
        {
            // 声明数据类型
            ResUser resData = new ResUser();
            string json = null;
            MyResponse myResponse = null;
            try
            {
                json = myJson.SerializeObject(postData);
                Debug.Print($"Request Url => {apiUrl}");
                Debug.Print($"Request Json => {json}");
                myResponse = myWeb.Post(apiUrl, json);
                //res = "[{" + Regex.Match(res, "(?<=(\\[\\{)).*(?=\\}\\])").Value + "}]";
                //Debug.Print($"res => {res}");
                    //ResUser res = myJson.DeserializeObject<ResUser>(myResponse.Datas);
                    //if (res == null)
                    //{
                    //    resData.message = "远程数据解析失败！";
                    //}
                    //else
                    //{
                    //    resData = res;
                    //}
            }
            catch (Exception ex)
            {
                Debug.Print($"request => {json}");
                Debug.Print($"res => {myResponse.Datas}");
                myLog.FileWriteLine(myLog.ERROR_DATE, ex.ToString());
                resData.message = ex.Message;
            }
            //resData.code = myResponse.Code;
            return myResponse;
        }
    }

    /// <summary>
    /// 打印类
    /// </summary>
    public class MyPrint
    {
        // 打印文档实例

        private PrintDocument printDocument = new PrintDocument();
        private readonly List<PrintList> printInfos;
        private readonly MyPrintInfo myPrintInfo;
        private readonly bool printBackImage = false;
        private readonly MyMargin myMargin;
        private readonly MyLog myLog = new MyLog();
        public class MyPrintInfo
        {
            public MyPrinter Printer { get; set; }
            public MyPaper Paper { get; set; }
            public MyPrintInfo(string printerName = "", string name = "保修卡", int rawKind = 999, float width = 210,
                float height = 285, MyMargin margin = default, bool landscape = true)
            {
                Printer = new MyPrinter(printerName);
                if (margin == default) { margin = new MyMargin(); }
                Paper = new MyPaper(name, rawKind, width, height, margin, landscape);
            }


            public class MyPrinter
            {
                public string Name { get; set; }
                public MyPrinter(string name)
                {
                    Name = name;
                }
            }

            public class MyPaper
            {
                public string Name { get; set; }

                private float _width;
                /// <summary>
                /// 纸张宽带度，单位inch/100
                /// </summary>
                public float Width
                {
                    get => _width;
                    set
                    {
                        _width = value > 0 ? value : 210;
                    }
                }

                private float _height;
                /// <summary>
                /// 纸张高度，单位inch/100
                /// </summary>
                public float Height
                {
                    get => _height;
                    set
                    {
                        _height = value > 0 ? value : 285;
                    }
                }
                public int RawKind { get; set; }
                public bool Landscape { get; set; }
                public MyMargin Margin { get; set; }

                /// <summary>
                /// 自定义纸张类New，调用时返回inch/100，
                /// 默认为A4：210×297mm，边距均为0mm
                /// </summary>
                /// <param name="name">纸张名称，默认为Custom</param>
                /// <param name="rawKind">纸张RawKind，默认为999</param>
                /// <param name="width">纸张宽带，单位mm</param>
                /// <param name="height">纸张高度，单位mm</param>
                /// <param name="margin">页边距，单位mm</param>
                /// <param name="height">横向,bool</param>
                public MyPaper(string name, int rawKind, float width, float height, MyMargin margin, bool landscape)
                {
                    Name = name;
                    RawKind = rawKind;
                    Width = width;
                    Height = height;
                    Landscape = landscape;
                    Margin = margin;
                }
            }
        }

        /// <summary>
        /// Printer类new函数
        /// </summary>
        /// <param name="configInfo">配置信息</param>
        /// <param name="userData">打印的数据</param>
        public MyPrint(ConfigInfo configInfo, UserData userData, bool isBackImage = false)
        {
            try
            {
                // 设置打印机
                SetPrinter();
                //设置纸张
                //SetPage();

                this.myPrintInfo = configInfo.MyPrintInfo;
                printBackImage = isBackImage;
                PrinterSettings printerSettings = new PrinterSettings()
                {
                    PrintRange = PrintRange.AllPages
                };
                //float X = printDocument.DefaultPageSettings.HardMarginX;
                //float Y = printDocument.DefaultPageSettings.HardMarginY ;
                myMargin = new MyMargin(printDocument.DefaultPageSettings.HardMarginX, printDocument.DefaultPageSettings.HardMarginY);
                PageSettings pageSettings = new PageSettings(printerSettings)
                {
                    PaperSize = new PaperSize
                    {
                        PaperName = myPrintInfo.Paper.Name,
                        RawKind = myPrintInfo.Paper.RawKind,
                        Width = (int)CInch(myPrintInfo.Paper.Width),
                        Height = (int)CInch(myPrintInfo.Paper.Height),
                    },
                    Margins = new Margins((int)myMargin.X, (int)myMargin.X, (int)myMargin.Y, (int)myMargin.Y),
                    //Margins = new Margins(0,0,0,0),
                    Landscape = myPrintInfo.Paper.Landscape,
                };
                printDocument.DefaultPageSettings = pageSettings;
                printDocument.OriginAtMargins = true;

                printDocument.PrintPage += new PrintPageEventHandler(this.PrintPage);

                if (userData == null) return;
                printInfos = new List<PrintList>()
            {
                new PrintList(37.5f,16.2f,90f,0,StringAlignment.Near, new Font("微软雅黑",14f,FontStyle.Bold),userData.用户名称),
                new PrintList(225.5f,16.0f,50.0f,0,StringAlignment.Far, new Font("微软雅黑", 13f,FontStyle.Bold), $"编号：{userData.编号}"),
                new PrintList(85f,200.5f,36.0f,0,StringAlignment.Near, new Font("微软雅黑", 20f,FontStyle.Bold), userData.金额?.ToString("F2")),
                new PrintList(239f,193.0f,12.0f,0,StringAlignment.Center, new Font("微软雅黑", 11f), userData.购买日期.ToString("yyyy")),
                new PrintList(252.5f,193.0f,8.0f,0,StringAlignment.Center, new Font("微软雅黑", 11f), userData.购买日期.ToString("MM")),
                new PrintList(261.5f,193.0f,8.0f,0,StringAlignment.Center, new Font("微软雅黑", 11f), userData.购买日期.ToString("dd")),
            };
                int i = 0;
                float rowHeight = 6.5f;
                float first = 75f;
                userData.配置.ForEach(item =>
                {
                    float y = first + rowHeight * i;
                    printInfos.Add(new PrintList(10.5f, y, 25f, 0, StringAlignment.Center, new Font("微软雅黑", 11f, FontStyle.Bold), item.类型));
                    printInfos.Add(new PrintList(37.5f, y, 52f, 0, StringAlignment.Near, new Font("微软雅黑", 11f), item.名称));
                    if (item.数量 > 0)
                        printInfos.Add(new PrintList(91f, y, 15f, 0, StringAlignment.Center, new Font("微软雅黑", 11f), item.数量.ToString()));
                    printInfos.Add(new PrintList(108f, y, 50f, 0, StringAlignment.Near, new Font("微软雅黑", 11f), item.保修));
                    i++;
                });
            }
            catch (Exception ex)
            {
                myLog.FileWriteLine(myLog.ERROR_DATE, ex.ToString());
            }
        }

        /// <summary>
        /// 打印信息类
        /// </summary>
        public class PrintList
        {
            /// <summary>
            /// X轴位置，单位inch/100
            /// </summary>
            public float X { get; set; }
            /// <summary>
            /// Y轴位置，单位inch/100
            /// </summary>
            public float Y { get; set; }
            public float Width { get; set; }
            public float Height { get; set; }
            public StringAlignment Alignent { get; set; }
            public Font Font { get; set; }
            public string Text { get; set; }

            /// <summary>
            /// 打印信息New，调用返回inch/100
            /// </summary>
            /// <param name="x">X轴位置，单位mm，会自动转换为inch/100</param>
            /// <param name="y">Y轴位置，单位mm，会自动转换为inch/100</param>
            /// <param name="alignent">对齐方式，默认左，可选左-1、右-2、中-3</param>
            /// <param name="font">Font类，默认为宋体，9pt</param>
            /// <param name="text">打印文本</param>
            public PrintList(float x, float y, float width, float height, StringAlignment alignent = default, Font font = null, string text = null)
            {
                X = CInch(x);
                Y = CInch(y);
                Width = CInch(width);
                Alignent = alignent;
                Font = font ?? new Font("宋体", 9f);
                Text = text;
                Height = height == 0 ? font.Height : CInch(height);
            }
        }


        /// <summary>
        /// 打印函数
        /// </summary>
        public void Print()
        {
            this.printDocument.Print();
        }

        /// <summary>
        /// 打印事件函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            Graphics g = e.Graphics;
            SolidBrush drawBrush = new SolidBrush(Color.Black);

            //Debug.Print($"{printDocument.DefaultPageSettings.PaperSize.PaperName}: " +
            //$"{printDocument.DefaultPageSettings.PaperSize.Width}, {printDocument.DefaultPageSettings.PaperSize.Height}");

            //背景图打印
            if (printBackImage)
                g.DrawImage(Resources.Background, -myMargin.X + CInch(myPrintInfo.Paper.Margin.X), -myMargin.Y + CInch(myPrintInfo.Paper.Margin.Y));
            //g.DrawImage(Resources.Background, 0, 0);

            if (printInfos != null)
            {
                foreach (PrintList info in printInfos)
                {
                    if (string.IsNullOrEmpty(info.Text))
                        continue;
                    Font drawFont = info.Font;
                    string drawString = info.Text.Trim();
                    float x = info.X + CInch(myPrintInfo.Paper.Margin.X) - myMargin.X;
                    float y = info.Y + CInch(myPrintInfo.Paper.Margin.Y) - drawFont.Height - myMargin.Y;
                    RectangleF drawRectF = new RectangleF(x, y, info.Width, info.Height);
                    StringFormat drawFormat = new StringFormat()
                    {
                        Alignment = info.Alignent
                    };

                    g.DrawString(drawString, drawFont, drawBrush, drawRectF, drawFormat);
                    //Debug.Print($"[{drawString}]=>位置：{CMm(info.X)}, {CMm(info.Y)},{CMm(info.X + info.Width)},{CMm(info.Y + info.Height)}");

                }
            }
        }

        /// <summary>
        /// 预览函数
        /// </summary>
        public void PreView()
        {
            PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog()
            {
                Document = printDocument,
                ClientSize = new Size(800, 600),
            };
            try
            {
                printPreviewDialog.ShowDialog();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "打印出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 设置打印机函数
        /// </summary>
        public void SetPrinter()
        {
            PrintDialog printDialog = new PrintDialog()
            {
                Document = printDocument
            };
            printDialog.ShowDialog();
            printDocument.PrinterSettings = printDialog.PrinterSettings;
        }

        /// <summary>
        /// 设置纸张函数
        /// </summary>
        public void SetPage()
        {
            printDocument.PrinterSettings.PrinterName = "";
            PageSetupDialog pageSetupDialog = new PageSetupDialog()
            {
                Document = printDocument
            };
            pageSetupDialog.ShowDialog();
        }

        public class MyMargin
        {
            public float X;
            public float Y;
            public MyMargin(float x = 0, float y = 0)
            {
                X = x;
                Y = y;
            }
        }

        /// <summary>
        /// 测量格式化文本内容大小
        /// </summary>
        /// <param name="text">文本内容</param>
        /// <param name="font">Font类</param>
        /// <param name="e">关联事件e</param>
        /// <returns>返回值为百分之一英寸</returns>
        private static SizeF GetTextSize(string text, Font font, PrintPageEventArgs e)
        {
            //TextFormatFlags flags = TextFormatFlags.NoPadding;
            //Size proposedSize = new Size(int.MaxValue, int.MaxValue);
            // TextFormatFlags flags = TextFormatFlags.NoPadding;
            //Size size = TextRenderer.MeasureText(e.Graphics, text, font, proposedSize, TextFormatFlags.NoPadding);
            SizeF sizeF = e.Graphics.MeasureString(text, font);
            return sizeF;
        }

        /// <summary>
        /// 毫米转换到百分之一英寸
        /// </summary>
        /// <param name="value">输入值，单位mm</param>
        /// <returns>返回值为百分之一英寸</returns>
        private static float CInch(float value)
        {
            return value * 100.0f / 25.4f;
            //return (float)(mm * 25.4f);
        }

        /// <summary>
        /// 毫米转换到百分之一英寸
        /// </summary>
        /// <param name="value">输入值，单位Inch/100</param>
        /// <returns>返回值为英寸</returns>
        private static float CMm(float value)
        {
            return (float)(value / 100 * 25.4f);
        }
    }
}
